package cc.chenwenxi.mypi.appium.kits;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.ImmutableMap;
import io.appium.java_client.MobileElement;
import io.appium.java_client.PerformsTouchActions;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;

import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

/**
 * Appium各种操作工具类
 */
@Data
@Slf4j
public class AppiumUtils {

    private final AndroidDriver driver;
    private final int height;
    private final int width;
    private final TouchAction touchAction;

    public AppiumUtils(AndroidDriver driver) {
        this.driver = driver;

        Dimension size = driver.manage().window().getSize();
        height = size.getHeight();
        width = size.getWidth();
        touchAction = new TouchAction(driver);
    }

    public File screenshot() {
        return driver.getScreenshotAs(OutputType.FILE);
    }

    public Object send(CharSequence template, Object... params){
        String format = StrUtil.format(template, params);
        String str = StrUtil.format("am broadcast -a ADB_INPUT_TEXT --es msg '{}'", format);
        return driver.executeScript("mobile:shell", ImmutableMap.of("command", str));
    }

    public Xy getPoint(MobileElement me){
        Dimension size = me.getSize();
        Point rect = me.getLocation();
        int x = rect.getX() + (size.getWidth() / 2);
        int y = rect.getY() + (size.getHeight() / 2);
        return new Xy(x,y);
    }

    public static record Xy(int x,int y){}

    public void click(Xy xy) {
        TouchAction touchAction = new TouchAction(driver);
        PointOption pointOption = PointOption.point(xy.x, xy.y);
        touchAction.press(pointOption).release().perform();
        log.info("点击坐标_x:{},y:{}",xy.x,xy.y);
    }

    public void click(MobileElement me,int addX,int addY) {
        Xy point = this.getPoint(me);
        int x = point.x + addX;
        int y = point.y + addY;
        TouchAction touchAction = new TouchAction(driver);
        PointOption pointOption = PointOption.point(x, y);
        touchAction.press(pointOption).release().perform();
        log.info("点击坐标_x:{},y:{}",x,y);
    }

    public boolean isExist(WebElement webElement) {
        try {
            return webElement.isDisplayed();
        } catch (Exception e) {
            log.warn("没有找到元素:{}", webElement);
        }
        return false;
    }

    /**
     * @module 上滑操作
     */
    public void swipeUp() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        PointOption pointOption = PointOption.point(width / 2, height * 3 / 4);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width / 2, height / 4)).release().perform();
    }
    public void swipeUpSmall() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        int yin = height / 8;
        PointOption pointOption = PointOption.point(width / 2, yin * 5);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width / 2, yin  *  4)).release().perform();
    }

    /**
     * @module 下滑操作
     */
    public void swipeDown() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        PointOption pointOption = PointOption.point(width / 2, height / 4);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width / 2, height * 3 / 4)).release().perform();
    }

    /**
     * @module 下滑操作
     */
    public void swipeDownSmall() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        int yin = height / 8;
        PointOption pointOption = PointOption.point(width / 2, yin * 3);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width / 2, yin * 5)).release().perform();
    }

    /**
     * @module 左滑操作
     */
    public void swipeLeft() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        PointOption pointOption = PointOption.point(width * 4 / 5, height / 2);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width / 5, height / 2)).release().perform();
    }

    /**
     * @module 右滑操作
     */
    public void swipeRight() {
        TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
        PointOption pointOption = PointOption.point(width / 5, height / 4);
        touchAction.press(pointOption).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).moveTo(PointOption.point(width * 4 / 5, height / 2)).release().perform();
    }

    /**
     * 执行测试前，检查各设备电量情况，电量不足发出警告
     *
     * @return 电量状态是否允许可继续执行
     */
    public Double checkBattery() {
        String message = "";
        double batteryLevel = driver.getBatteryInfo().getLevel();
        String batteryState = driver.getBatteryInfo().getState().name();
        return batteryLevel;
    }

    /**
     * 执行测试前，检查网络状态
     *
     * @return 网络连接状态
     */
    public String checkNetwork() {
        List<String> networkList = new ArrayList<>();
        String message = "";
        boolean wiFiEnabled = driver.getConnection().isWiFiEnabled();
        if (!true == wiFiEnabled) {
            message = "ERROR";
        }
        if (true == wiFiEnabled) {
            message = "WIFI";
        }
        return message;
    }
}